/************************************************************
 * Project Name         [Thinking_In_Java]
 * File Name            [Example_06_Logging.java]
 * Creation Date        [27-Jun-2014]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ************************************************************/
package pkg_03_miscellaneous;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.logging.ConsoleHandler;
import java.util.logging.FileHandler;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

/**
 * Java Logging API
 * 
 * @author 不落的太阳(Sean Yang)
 * @version 1.0
 * @since JDK 6
 * 
 */
public class Example_06_Logging {

	private static final Logger LOGGER = Logger
			.getLogger(Example_06_Logging.class.getName());

	public void doSomethingAndLog() {
		// set the LogLevel to Severe, only severe Messages will be written
		LOGGER.setLevel(Level.SEVERE);
		LOGGER.severe("Info Log");
		LOGGER.warning("Info Log");
		LOGGER.info("Info Log");
		LOGGER.finest("Really not important");

		// set the LogLevel to Info, severe, warning and info will be written
		// finest is still not written
		LOGGER.setLevel(Level.INFO);
		LOGGER.severe("Info Log");
		LOGGER.warning("Info Log");
		LOGGER.info("Info Log");
		LOGGER.finest("Really not important");
	}

	/**
	 * 测试方法
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		Example_06_Logging el = new Example_06_Logging();
		try {
			SimpleLogger.setup();
		} catch (IOException e) {
			e.printStackTrace();
		}

		el.doSomethingAndLog();
	}

}

/**
 * 简单的日志类
 * 
 * @author 不落的太阳(Sean Yang)
 * @version 1.0
 * @since JDK 6
 * 
 */
class SimpleLogger {

	private static FileHandler fileHandler;
	private static SimpleFormatter simpleFormatter;

	private static FileHandler htmlHandler;
	private static Formatter htmlFormatter;

	public static void setup() throws IOException {
		Logger logger = Logger.getLogger(SimpleLogger.class.getName());

		// 不输出到控制台
		Logger rootLogger = Logger.getLogger("");
		Handler[] handlers = rootLogger.getHandlers();
		System.out.println("Handlers === " + Arrays.toString(handlers));
		if (handlers[0].getClass() == ConsoleHandler.class) {
			rootLogger.removeHandler(handlers[0]);
		}

		logger.setLevel(Level.INFO);

		fileHandler = new FileHandler(
				"src_01_language_basic/pkg_resources/logging.txt");
		simpleFormatter = new SimpleFormatter();
		fileHandler.setFormatter(simpleFormatter);
		logger.addHandler(fileHandler);

		htmlHandler = new FileHandler(
				"src_01_language_basic/pkg_resources/logging.html");
		htmlFormatter = new HTMLFormatter();
		htmlHandler.setFormatter(htmlFormatter);
		logger.addHandler(htmlHandler);
	}
}

/**
 * 一个自定义的formatter
 * 
 * @author 不落的太阳(Sean Yang)
 * @version 1.0
 * @since JDK 6
 * 
 */
class HTMLFormatter extends Formatter {

	@Override
	public String format(LogRecord record) {
		StringBuffer buffer = new StringBuffer();
		buffer.append("<tr>\n");

		// 高于warning的日志会被红色高亮
		if (record.getLevel().intValue() >= Level.WARNING.intValue()) {
			buffer.append("\t<td style=\"color:red\">");
			buffer.append("<b>");
			buffer.append(record.getLevel());
			buffer.append("</b>");
		} else {
			buffer.append("\t<td>");
			buffer.append(record.getLevel());
		}
		buffer.append("</td>\n");
		buffer.append("\t<td>");
		buffer.append(calculateDate(record.getMillis()));
		buffer.append("</td>\n");
		buffer.append("\t<td>");
		buffer.append(formatMessage(record));
		buffer.append("</td>\n");
		buffer.append("</tr>\n");

		return buffer.toString();
	}

	private String calculateDate(long millisecs) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
		Date resultDate = new Date(millisecs);
		return sdf.format(resultDate);
	}

	@Override
	public String getHead(Handler h) {
		return "<!DOCTYPE html>\n<html>\t<head>\n<style "
				+ "type=\"text/css\">\n" + "table { width: 100% }\n"
				+ "th { font:bold 10pt Tahoma; }\n"
				+ "td { font:normal 10pt Tahoma; }\n"
				+ "h1 {font:normal 11pt Tahoma;}\n" + "</style>\n"
				+ "\t<title>Log List</title>" + "</head>\n" + "<body>\n"
				+ "<h1>" + (new Date()) + "</h1>\n"
				+ "<table border=\"0\" cellpadding=\"5\" cellspacing=\"3\">\n"
				+ "<tr align=\"left\">\n"
				+ "\t<th style=\"width:10%\">Loglevel</th>\n"
				+ "\t<th style=\"width:15%\">Time</th>\n"
				+ "\t<th style=\"width:75%\">Log Message</th>\n" + "</tr>\n";

	}

	@Override
	public String getTail(Handler h) {
		return "</table>\n</body>\n</html>";
	}

}
